package com.icinfo.cloud.provider.common.utils;

import cn.hutool.core.util.ObjectUtil;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.framework.tools.utils.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;

/**
 * 描述：日期常用工具类
 *
 * @author xiangyuyu
 * @date 2022/3/5 16:01
 */
public class DateUtil {

    // 各种时间格式
    public static final String date_sdf = "yyyy-MM-dd";
    // 各种时间格式
    public static final String yyyyMMdd = "yyyyMMdd";

    public static final String time_sdf = "yyyy-MM-dd HH:mm";
    public static final String yyyymmddhhmmss = "yyyyMMddHHmmss";
    public static final String yyyymmddhhmmsss = "yyyyMMddHHmmsss";
    public static final String hhmmsss = "HHmmsss";
    public static final String short_time_sdf = "HH:mm";
    public static final String datetimeFormat = "yyyy-MM-dd HH:mm:ss";
    public static final String date_sdf_wz = "yyyy年MM月dd日";
    // 各种时间格式
    public static final String datetime_wz = "yyyy年MM月dd日HH时mm分";
    public static final String date_sdf_wz_format = "yyyy年M月d日";
    public static final String time_wz = "HH时mm分";
    public static final String datehour_wz_format = "yyyy年M月d日HH时mm分";
    public static final String datetime_wz_format = "yyyy年M月d日HH时mm分ss秒";

    //格式名称
    public static final String DATE_FORMAT_NAME1 = "datehour";
    public static final String DATE_FORMAT_NAME2 = "datetime";
    public static final String DATE_FORMAT_NAME3 = "date";
    public static final String DATE_FORMAT_NAME4 = "time";

    /**
     * 描述：计算时间间隔信息
     *
     * @param startTime      计算开始时间
     * @param endTime        计算结束时间
     * @param isOptimizeShow 是否优化显示
     * @return Map<String, String> （sign=0 时间相等/sign>0 开始时间小于结束时间/sign<0 开始时间大于结束时间）
     * @author xiangyuyu
     * @date 2022-03-05 15:52
     */
    public static HashMap<String, String> calculateTimeIntervalInfo(LocalDateTime startTime, LocalDateTime endTime, boolean isOptimizeShow) {
        HashMap<String, String> map = new HashMap<>(2);
        /*
        startTime > endTime:1
        startTime < endTime:2
        startTime = endTime:0
         */
        String sign = Constant.STRING_0;
        Duration duration = Duration.between(startTime, endTime);
        long daysShow = 0;
        long hoursShow = 0;
        long minutesShow = 0;
        long minutes = duration.toMinutes();
        if (minutes != Constant.INTEGER_0) {
            daysShow = minutes / 1440;
            long temp = minutes - (daysShow * 1440);
            hoursShow = temp / 60;
            minutesShow = temp % 60;
        }
        if (minutes > 0) {
            sign = Constant.STRING_1;
        } else if (minutes < 0) {
            sign = Constant.STRING_2;
        }
        String showTime;
        if (isOptimizeShow) {
            if (Constant.INTEGER_0 == daysShow) {
                if (Constant.INTEGER_0 == hoursShow) {
                    showTime = minutesShow + "分";
                } else {
                    showTime = hoursShow + "时" + minutesShow + "分";
                }
            } else {
                showTime = daysShow + "天" + hoursShow + "时" + minutesShow + "分";
            }
        } else {
            showTime = daysShow + "天" + hoursShow + "时" + minutesShow + "分";
        }
        map.put("sign", sign);
        map.put("showTime", showTime);
        return map;
    }

    /**
     * 描述：计算时间间隔信息(去除暂停)
     *
     * @param startTime      计算开始时间
     * @param endTime        计算结束时间
     * @param isOptimizeShow 是否优化显示
     * @return Map<String, String> （sign=0 时间相等/sign>0 开始时间小于结束时间/sign<0 开始时间大于结束时间）
     * @author xiangyuyu
     * @date 2022-03-05 15:52
     */
    public static HashMap<String, String> calculateSuspendTimeIntervalInfo(LocalDateTime startTime, LocalDateTime endTime, long suspendDays, boolean isOptimizeShow) {
        HashMap<String, String> map = new HashMap<>(2);
        /*
        startTime > endTime:1
        startTime < endTime:2
        startTime = endTime:0
         */
        String sign = Constant.STRING_0;
        Duration duration = Duration.between(startTime, endTime);
        if (ObjectUtil.isNotEmpty(suspendDays)) {
            duration = duration.plusDays(suspendDays);
        }
        long daysShow = 0;
        long hoursShow = 0;
        long minutesShow = 0;
        long minutes = duration.toMinutes();
        if (minutes != Constant.INTEGER_0) {
            daysShow = minutes / 1440;
            long temp = minutes - (daysShow * 1440);
            hoursShow = temp / 60;
            minutesShow = temp % 60;
        }
        if (minutes > 0) {
            sign = Constant.STRING_1;
        } else if (minutes < 0) {
            sign = Constant.STRING_2;
        }
        String showTime;
        if (isOptimizeShow) {
            if (Constant.INTEGER_0 == daysShow) {
                if (Constant.INTEGER_0 == hoursShow) {
                    showTime = minutesShow + "分";
                } else {
                    showTime = hoursShow + "时" + minutesShow + "分";
                }
            } else {
                showTime = daysShow + "天" + hoursShow + "时" + minutesShow + "分";
            }
        } else {
            showTime = daysShow + "天" + hoursShow + "时" + minutesShow + "分";
        }

        map.put("sign", sign);
        map.put("showTime", showTime);
        return map;
    }

    /**
     * 描述: 获取目标日期截止到现在的天数
     *
     * @param localDate
     * @return long
     * @author shishengyao
     * @date 2022/06/21
     */
    public static long calculatePastDays(LocalDate localDate) {
        LocalDate now = LocalDate.now();
        long until = localDate.until(now, ChronoUnit.DAYS);
        return until;
    }

    /**
     * @param dateStr str日期
     * @return {@link String }
     * @author shishengyao
     * @date 2022/08/31
     */
    public static String formatDateStr(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return "";
        }
        String outDateStr = dateStr;
        String validDate = isValidDate(dateStr);
        String backStr = "";
        if (null != validDate) {
            //截取日期后的字符串
            if (dateStr.length() > validDate.length()) {
                backStr = dateStr.substring(validDate.length(), dateStr.length());
            }
            SimpleDateFormat sdf = null;
            if (validDate.contains("dd") && validDate.length() <= 11) {
                sdf = new SimpleDateFormat(date_sdf_wz_format);
            }
            if (validDate.contains("HH") && validDate.length() > 11) {
                sdf = new SimpleDateFormat(datehour_wz_format);
            }
            if (validDate.contains("ss") && validDate.length() > 11) {
                sdf = new SimpleDateFormat(datetime_wz_format);
            }
            //转换成Date对象
            Date tempDate = null;
            try {
                SimpleDateFormat oldSdf = new SimpleDateFormat(validDate);
                tempDate = oldSdf.parse(dateStr);
                //Date对象转换成String
                outDateStr = sdf.format(tempDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }
        return outDateStr + backStr;
    }

    /**
     * 描述：将日期格式化成标准格式
     *
     * @param dateStr str日期
     * @return {@link String }
     * @author shishengyao
     * @date 2022/08/31
     */
    public static String formatDate(String dateStr, String simpleDateFormat, String pickerType) {
        if (StringUtils.isEmpty(dateStr)) {
            return "";
        }
        try {
            // todo 适配不同的时间格式， 目前只处理（yyyy年M月d日HH时mm分ss秒）
            String validDate = isValidDate(dateStr);
            SimpleDateFormat df = new SimpleDateFormat(validDate);
            Date parse = df.parse(dateStr);
            String str1 = "";
            simpleDateFormat = simpleDateFormat.replace(" HH", "HH");
            if (DATE_FORMAT_NAME2.equals(pickerType) && simpleDateFormat.contains("ss")) {
                simpleDateFormat = simpleDateFormat.substring(0, simpleDateFormat.indexOf("ss"));
            } else if (DATE_FORMAT_NAME1.equals(pickerType) && simpleDateFormat.contains("mm")) {
                simpleDateFormat = simpleDateFormat.substring(0, simpleDateFormat.indexOf("mm"));
            } else if (DATE_FORMAT_NAME3.equals(pickerType) && simpleDateFormat.contains("HH")) {
                if (simpleDateFormat.contains(" HH")) {
                    simpleDateFormat = simpleDateFormat.substring(0, simpleDateFormat.indexOf(" HH"));
                } else {
                    simpleDateFormat = simpleDateFormat.substring(0, simpleDateFormat.indexOf("HH"));
                }
            } else if (DATE_FORMAT_NAME4.equals(pickerType) && simpleDateFormat.contains("HH")) {
                str1 = simpleDateFormat.substring(0, simpleDateFormat.indexOf("HH"));
                simpleDateFormat = simpleDateFormat.substring(str1.length());
            }
            SimpleDateFormat sdf = new SimpleDateFormat(simpleDateFormat);
            String dateString = sdf.format(parse);
            dateStr = dateString;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dateStr;
    }

    /**
     * 验证时间格式是否符合
     *
     * @param str
     * @return
     */
    public static String isValidDate(String str) {
        boolean convertSuccess = true;
        String type = null;
        SimpleDateFormat sdf = null;
        try {
            sdf = new SimpleDateFormat(datetime_wz);
            sdf.setLenient(false);
            if (sdf.parse(str) != null) {
                convertSuccess = true;
                type = datetime_wz;
            }
        } catch (Exception e) {
            try {
                sdf = new SimpleDateFormat(datetimeFormat);
                sdf.setLenient(false);
                if (sdf.parse(str) != null) {
                    convertSuccess = true;
                    type = datetimeFormat;
                }
            } catch (Exception e1) {
                try {
                    sdf = new SimpleDateFormat(time_sdf);
                    sdf.setLenient(false);
                    if (sdf.parse(str) != null) {
                        convertSuccess = true;
                        type = time_sdf;
                    }
                } catch (Exception e2) {
                    try {
                        sdf = new SimpleDateFormat(date_sdf);
                        sdf.setLenient(false);
                        if (sdf.parse(str) != null) {
                            convertSuccess = true;
                            type = date_sdf;
                        }
                    } catch (Exception e3) {
                        try {
                            sdf = new SimpleDateFormat(yyyyMMdd);
                            sdf.setLenient(false);
                            if (sdf.parse(str) != null) {
                                convertSuccess = true;
                                type = yyyyMMdd;
                            }
                        } catch (Exception e4) {
                            try {
                                sdf = new SimpleDateFormat(date_sdf_wz);
                                sdf.setLenient(false);
                                if (sdf.parse(str) != null) {
                                    convertSuccess = true;
                                    type = date_sdf_wz;
                                }
                            } catch (Exception e5) {
                                convertSuccess = false;
                            }
                        }
                    }
                }
            }
        }
        if (convertSuccess == true) {
            return type;
        }
        return null;
    }

    /**
     * 验证时间
     *
     * @param str
     * @return
     * @throws ParseException
     */
    public static boolean compDate(String str){
        //2022年12月13日
        SimpleDateFormat sd = new SimpleDateFormat("yyyy年MM月dd");
        Date date = new Date();
        int i = 0;
        try {
            i = date.compareTo(sd.parse(str));
        } catch (ParseException e) {
            e.printStackTrace();
            throw new BusinessException("日期验证失败");
        }
        if (i>0){
            return false;
        }else {
            return true;
        }
    }
    /**
     * 验证时间格式是否符合
     * @param str
     * @return
     */
//    public static SimpleDateFormat isValidDate2(String str)  {
//        boolean convertSuccess=true;
//        SimpleDateFormat type =null;
//        try {
//            date_sdf.setLenient(false);
//            if(date_sdf.parse(str) != null){
//                convertSuccess=true;
//                type=date_sdf;
//            }
//        } catch (Exception e) {
//            try {
//                yyyyMMdd.setLenient(false);
//                if(yyyyMMdd.parse(str) != null){
//                    convertSuccess=true;
//                    type=yyyyMMdd;
//                }
//            } catch (Exception e1) {
//                try {
//                    date_sdf_wz.setLenient(false);
//                    if(date_sdf_wz.parse(str) != null){
//                        convertSuccess=true;
//                        type=date_sdf_wz;
//                    }
//                } catch (Exception e2) {
//                    try {
//                        yyyymmddhhmmss.setLenient(false);
//                        if(yyyymmddhhmmss.parse(str) != null){
//                            convertSuccess=true;
//                            type=yyyymmddhhmmss;
//                        }
//                    } catch (Exception e3) {
//                        try {
//                            datetimeFormat.setLenient(false);
//                            if(datetimeFormat.parse(str) != null){
//                                convertSuccess=true;
//                                type=datetimeFormat;
//                            }
//                        } catch (Exception e4) {
//                            try {
//                                time_sdf.setLenient(false);
//                                if(time_sdf.parse(str) != null){
//                                    convertSuccess=true;
//                                    type=time_sdf;
//                                }
//                            } catch (Exception e5) {
//                                try {
//                                    short_time_sdf.setLenient(false);
//                                    if(short_time_sdf.parse(str) != null){
//                                        convertSuccess=true;
//                                        type=short_time_sdf;
//                                    }
//                                } catch (ParseException e6) {
//                                    convertSuccess=false;
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//        }
//        if(convertSuccess==true){
//            return type;
//        }
//        return null;
//    }

    public static String getCurrentFormatTime() {
        SimpleDateFormat sd = new SimpleDateFormat(yyyymmddhhmmss);
        return sd.format(new Date());
    }

}
